#include <cstdlib>
#include "swf.h"
#include "zlib.h"
#include "png.h"
#include "DefineBitsLossless.h"
using namespace swfstream;

DefineBitsLossless* DefineBitsLossless::from_file(FILE* f, uint tag_length) {
	uint size = ftell(f);
	DefineBitsLossless*r = new DefineBitsLossless;
	uint16 tmp;
	fread(&tmp, 2, 1, f);
	if (feof(f)) {
		puts("FEOF!");
		exit(98);
	}
	//printf("CharacterID=%u\n",(uint)tmp);
	r->CharacterID = tmp;
	r->BitmapFormat = getc(f);
	if (feof(f)) {
		puts("FEOF!");
		exit(98);
	}
	//printf("BitmapFormat=%u\n",(uint)r->BitmapFormat);
	fread(&tmp, 2, 1, f);
	if (feof(f)) {
		puts("FEOF!");
		exit(98);
	}
	//printf("BitmapWidth=%u\n",(uint)tmp);
	r->BitmapWidth = tmp;
	fread(&tmp, 2, 1, f);
	if (feof(f)) {
		puts("FEOF!");
		exit(98);
	}
	//printf("BitmapHeight=%u\n",(uint)tmp);
	r->BitmapHeight = tmp;
	if (r->BitmapFormat == 3) {
		r->BitmapColorTableSize = getc(f);
		if (feof(f)) {
			puts("FEOF!");
			exit(98);
		}
		//printf("BitmapColorTableSize=%u\n",(uint)r->BitmapColorTableSize);
	}
	size = ftell(f) - size;
	size = tag_length - size;
	if (r->BitmapFormat == 3) {
		byte *z = new byte[size];
		//printf("sizeof z=%u\n",size);
		fread(z, size, 1, f);
		if (feof(f)) {
			puts("FEOF!");
			exit(98);
		}
		uLong size_u = size * 100;
		byte* u = new byte[size_u];
		//printf("size_u=%lu\n",size_u);
		int ru = uncompress(u, &size_u, z, size);
		//printf("size_u=%lu,r=%d\n",size_u,ru);
		r->ZlibBitmapData = COLORMAPDATA::from_mem(u, (uint) size_u,
				r->BitmapColorTableSize + 1, r->BitmapWidth, r->BitmapHeight);
		//r->ZlibBitmapData=COLORMAPDATA::from_file(f,r->BitmapColorTableSize+1,r->BitmapWidth*r->BitmapHeight);
	} else if ((r->BitmapFormat == 4) || (r->BitmapFormat == 5)) {
		printf("DefineBitsLossless::from_file,not finished\n");
		exit(99);
	}
	//exit(99);
	return r;
}
void DefineBitsLossless::print() {
}
/*
 COLORMAPDATA* COLORMAPDATA::from_file(FILE* f,uint color_table_size,uint image_data_size){
 COLORMAPDATA*r=new COLORMAPDATA;
 r->ColorTableRGB=new std::vector<RGB*>;
 r->ColormapPixelData=new std::vector<uint8>;
 for(uint i=0;i<color_table_size;i++){
 r->ColorTableRGB->push_back(RGB::from_file(f));
 }
 for(uint i=0;i<image_data_size;i++){
 byte tmp=getc(f);
 if(feof(f)){
 puts("FEOF! in COLORMAPDATA");
 exit(98);
 }
 //printf("%u ",(uint)tmp);
 //r->ColormapPixelData->push_back(tmp);
 }
 return r;
 }
 */
COLORMAPDATA* COLORMAPDATA::from_mem(byte* mem, uint mem_size,
		uint color_table_size, uint width, uint height) {
	COLORMAPDATA*r = new COLORMAPDATA;
	r->ColorTableRGB = new std::vector<RGB*>;
	//r->ColormapPixelData=new std::vector<uint8>;
	uint offset = 0;
	for (uint i = 0; i < color_table_size; i++) {
		RGB *rgb = new RGB;
		rgb->r = *(mem + offset);
		offset++;
		rgb->g = *(mem + offset);
		offset++;
		rgb->b = *(mem + offset);
		offset++;
		r->ColorTableRGB->push_back(rgb);
		rgb->print();
		//r->ColorTableRGB->push_back(RGB::from_file(f));
	}
	r->ColormapPixelData = mem + offset;
	uint r_width;
	if (width % 4 != 0) {
		r_width = width / 4 * 4 + 4;
	} else {
		r_width = width;
	}
	for (uint i = 0; i < r_width * height; i++) {
		//printf("%u ",(uint)*(mem+offset));
		if ((i + 1) % r_width == 0) {
			//	putchar('\n');
		}
		offset++;
		//byte tmp=getc(f);
		if (offset > mem_size) {
			puts("MEOF! in COLORMAPDATA");
			exit(97);
		}
		if (offset == mem_size) {
			puts("rech end! in COLORMAPDATA");
		}
		//printf("%u ",(uint)tmp);
		//r->ColormapPixelData->push_back(tmp);
	}
	return r;
}
void COLORMAPDATA::print() {
}
bool DefineBitsLossless::to_png(const char* fname) {
	if (BitmapFormat == 3) {
		uint width = BitmapWidth;
		uint height = BitmapHeight;
		uint table_width;
		byte* table;
		//puts("ppppppppppppppppppppppppppppppppppppppp");
		COLORMAPDATA* data = (COLORMAPDATA*) (ZlibBitmapData);
		table = data->ColormapPixelData;
		if (width % 4 != 0) {
			table_width = width / 4 * 4 + 4;
		} else {
			table_width = width;
		}

		FILE *fp = fopen(fname, "wb");

		png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
				NULL, NULL, NULL);
		png_init_io(png_ptr, fp);

		png_infop info_ptr = png_create_info_struct(png_ptr);
		//const int width  = 120;
		//const int height = 512;
		png_set_IHDR(png_ptr, info_ptr, width, height, 8,
				PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
				PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

		//png_colorp palette = (png_colorp)png_malloc(png_ptr,PNG_MAX_PALETTE_LENGTH * sizeof (png_color));
		if (PNG_MAX_PALETTE_LENGTH < data->ColorTableRGB->size()) {
			fprintf(stderr, "error:libpng not sopport color number:%u\n",
					(uint) data->ColorTableRGB->size());
			exit(1);
		}
		png_colorp palette = (png_colorp) png_malloc(png_ptr,
				data->ColorTableRGB->size() * sizeof(png_color));
		for (uint i = 0; i < data->ColorTableRGB->size(); ++i) {
			palette[i].red = data->ColorTableRGB->at(i)->r;
			palette[i].green = data->ColorTableRGB->at(i)->g;
			palette[i].blue = data->ColorTableRGB->at(i)->b;
		}
		png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);

		png_write_info(png_ptr, info_ptr);

		png_uint_32 k;

		//	png_byte image[height][width];
		png_bytep row_pointers[height];

		for (k = 0; k < height; k++) {
			row_pointers[k] = table + k * table_width;
		}

		png_write_image(png_ptr, row_pointers);
		png_write_end(png_ptr, info_ptr);

		png_free(png_ptr, palette);
		png_destroy_write_struct(&png_ptr, &info_ptr);
		fclose(fp);
	} else {
		fprintf(stderr, "main:DefineBitsLossless,type!=3,not finished");
		exit(1);
	}
	return true;
}
